package prologTranslator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

public class HechosStructure {
	
	private HashMap hechos_posicion = new HashMap();
	private HashMap hechos = new HashMap();
	private ArrayList hechos_a_agregar = new ArrayList();
	// indica cual es el nombre del fact usado por cada sig (si es que tiene
	// un appended fact)
	private HashMap factSig = new HashMap();
	
	public void add_hecho_en_pos(Integer posicion,Object hecho)
	{
		hechos_posicion.put(posicion,hecho);
	}
	
	private Object get_hecho_en_pos(Integer posicion)
	{
		return hechos_posicion.get(posicion);
	}
	
	public String getFactSig(String sig)
	{
		if(sig.contains("_"))
		{
			sig = sig.substring(0,sig.indexOf("_"));
		}
		if(factSig.containsKey(sig))
		{
			return (String) factSig.get(sig);
		}
		return "";
	}
	
	public void addFactSig(String sig, String fact)
	{
		if(sig.contains("_"))
		{
			sig = sig.substring(0,sig.indexOf("_"));
		}
		this.factSig.put(sig,fact);
	}
	
	public void delFactSig(String sig)
	{
		if(sig.contains("_"))
		{
			sig = sig.substring(0,sig.indexOf("_"));
		}
		if(this.factSig.containsKey(sig))
		{
			this.factSig.remove(sig);
		}
	}
	
	public HashMap getFacts()
	{
		return this.factSig;
	}
	
	public boolean containsFactSig(String sig)
	{
		if(sig.contains("_"))
		{
			sig = sig.substring(0,sig.indexOf("_"));
		}
		return this.factSig.containsKey(sig);
	}
	
	public void generar_hechos(String nombre_sig)
	{
		String st_gral = new String(""); //= new String(nombre_sig + "(OUT),\n\t");
		int  cont_relaciones = 0;
		for(int i=1; i<=hechos_posicion.size();i++)
		{
			st_gral = st_gral + (String) hechos_posicion.get(new Integer(i)) + "(X_" + i + "),\n\t";		
			cont_relaciones++;
		}
		
		// Si tiene una sola relacion, simplemente se borra a esta del mundo
		if(cont_relaciones == 1)
		{
			st_gral = st_gral + "retract(" + nombre_sig + "([X_1])),\n\t";
		}
		else
		{
			int cont_out_append = 0;
			for(int i=1; i<=cont_relaciones; i++)
			{
				if(i==1)
				{
					st_gral = st_gral + "append([X_1],[X_2],OUT_APPEND_0),\n\t";
					i=2;
				}
				else
				{
					st_gral = st_gral + "append(OUT_APPEND_" + cont_out_append + ",[X_" + i + "],OUT_APPEND_" + (++ cont_out_append) + "),\n\t";
				}
			}
			st_gral = st_gral + "retract(" + nombre_sig + "(OUT_APPEND_" + cont_out_append + ")),\n\t"; 
		}
		//st_gral = st_gral + "retract(" + nombre_sig + "(OUT)),\n\t";
		
		for(int i=1; i<=hechos_posicion.size();i++)
		{
			String st = new String("");
			st = st + "agregarAlMundo_" + (String) this.get_hecho_en_pos(new Integer(i)) + "(X_0):-\n\t" + st_gral;
			st = st + "append(X_0,X_" + i + ",OUT_0),\n\t";
			if(hechos_posicion.size()>1)
			{
				boolean entrar = true;
				int j;
				int count_OUT = 1;
				for(j=1; (j<=hechos_posicion.size());j++)
				{
					if((i>2)||(!entrar))
					{
						if(j==i)
						{
							st = st + "append(OUT_" + count_OUT + ",[OUT_0],OUT_" + ++count_OUT + "),\n\t";
						}
						else
						{
							if(j==1)
							{
								st = st + "append([X_1],[X_2],OUT_1),\n\t";
								j=2;
							}
							else
							{
								st = st + "append(OUT_" + count_OUT + ",[X_" + j + "],OUT_" + ++count_OUT + "),\n\t";
							}
						}
					}
					if((i==1)&&(entrar))
					{
						st = st + "append([OUT_0],[X_2],OUT_1),\n\t";
						entrar = false;
						j=2;
					}	
					if((i==2)&&(entrar))
					{
						st = st + "append([X_1],[OUT_0],OUT_1),\n\t";
						entrar = false;
						j=2;
					}							
				}
				st = st + "assert("+ nombre_sig +"(OUT_" + count_OUT + ")).\n\n";
			}
			else
			{
				st = st + "assert("+ nombre_sig +"([OUT_0])).\n\n";
			}
			hechos.put(hechos_posicion.get(new Integer(i)),st);
		}
		hechos_posicion.clear();
	}
	
	/*public void generar_hecho_atom(String type)
	{
		String st = "agregarAlMundo_" + type + "(X),\n\t";
		st = st + type + "(Y),\n\t";
		st = st + "retract(" + type + "(Y)),\n\t";
		st = st + "append(Y,X,OUT),\n\t";
		st = st + "assert(" + type + "(OUT)).\n\n";
		
		this.add_hecho_a_agregar(type);
		
		hechos.put(type ,st);
	}*/
	
	public void add_hecho_a_agregar(String hecho)
	{
		if(!hechos_a_agregar.contains(hecho))
		{
			hechos_a_agregar.add(hecho);
		}
	}
	
	public ArrayList get_hecho_a_agregar()
	{
		return hechos_a_agregar;
	}
		
	public String hechos_utilizados()
	{
		Iterator it = hechos_a_agregar.iterator();
		String st = new String("");
		
		while(it.hasNext())
		{
			st = st + hechos.get((String) it.next());
		}
		
		return st;
	}
	
}
